package com.nowcoder.community.quartz;

import com.nowcoder.community.constant.CommunityConstant;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.service.DiscussPostService;
import com.nowcoder.community.service.ElasticsearchService;
import com.nowcoder.community.service.LikeService;
import com.nowcoder.community.util.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author 花木凋零成兰
 * @date 2024/3/31 17:04
 */
@Slf4j(topic = "PostScoreRefreshJob.class")
public class PostScoreRefreshJob implements Job {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private DiscussPostService discussPostService;

    @Resource
    private LikeService likeService;

    @Resource
    private ElasticsearchService elasticsearchService;

    /**
     * 牛客纪元
     */
    private static final Date epoch;

    static {
        try {
            epoch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-08-01 00:00:00");
        } catch (ParseException e) {
            throw new RuntimeException("初始化牛客纪元失败!", e);
        }
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String redisKey = RedisKeyUtil.getPostScoreKey();
        BoundSetOperations operations = redisTemplate.boundSetOps(redisKey);
        if (operations.size() == 0) {
            log.warn("[任务取消] 没有需要刷新的帖子!");
            return ;
        }
        log.info("[任务开始] 正在刷新帖子分数：" + operations.size());
        while (operations.size() > 0) {
            this.refresh((Integer)operations.pop());
        }
        log.info("[任务结束] 帖子分数刷新完毕!");
    }

    private void refresh(int postId) {
        DiscussPost discussPost = discussPostService.findDiscussPostById(postId);

        if (discussPost == null) {
            log.error("该帖子不存在：{}", postId);
            return ;
        }
        // 是否加精
        boolean wonderful = discussPost.getStatus() == 1;
        // 评论数量
        int commentCount = discussPost.getCommentCount();
        // 点赞数量
        long likeCount = likeService.findEntityLikeCount(CommunityConstant.ENTITY_TYPE_POST, postId);

        // 计算权重
        double w = (wonderful ? 75 : 0) + commentCount * 10L + likeCount * 2;
        // 分数 = 帖子权重  + 距离天数
        double score = Math.log10(Math.max(w, 1.0))
                + (discussPost.getCreateTime().getTime() - epoch.getTime()) / (1000.0 * 3600 * 24);
        log.warn("帖子{}分数：{}", postId, score);

        // 更新帖子分数
        discussPostService.updateScore(postId, score);

        // 同步搜索的数据
        discussPost.setScore(score);
        elasticsearchService.saveDiscussPost(discussPost);

    }

}
